package com.zhiche.wms.service.base.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.zhiche.wms.core.supports.BaseException;
import com.zhiche.wms.core.supports.enums.TableStatusEnum;
import com.zhiche.wms.core.utils.SnowFlakeId;
import com.zhiche.wms.domain.mapper.base.StorehouseMapper;
import com.zhiche.wms.domain.model.base.NodeOption;
import com.zhiche.wms.domain.model.base.Storehouse;
import com.zhiche.wms.domain.model.base.StorehouseNode;
import com.zhiche.wms.domain.model.sys.User;
import com.zhiche.wms.dto.sys.StorehouseDTO;
import com.zhiche.wms.dto.sys.StorehouseNodeDTO;
import com.zhiche.wms.service.base.IStorehouseService;
import com.zhiche.wms.service.sys.INodeOptionService;
import com.zhiche.wms.service.sys.IStorehouseNodeService;
import com.zhiche.wms.service.sys.IUserService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 仓库信息 服务实现类
 * </p>
 *
 * @author qichao
 * @since 2018-06-08
 */
@Service
public class StorehouseServiceImpl extends ServiceImpl<StorehouseMapper, Storehouse> implements IStorehouseService {

    @Autowired
    private INodeOptionService optionService;
    @Autowired
    private SnowFlakeId flakeId;
    @Autowired
    private IUserService userService;
    @Autowired
    private IStorehouseNodeService storehouseNodeService;

    /**
     * 仓库配置 - 查询仓库列表查询
     */
    @Override
    public Page<Storehouse> listStoreHousePage(Page<Storehouse> page) {
        if (page == null) {
            throw new BaseException("page参数不能为空");
        }
        Map<String, Object> cn = page.getCondition();
        EntityWrapper<Storehouse> shEw = new EntityWrapper<>();
        if (cn.get("name") != null && StringUtils.isNotBlank(cn.get("name").toString())) {
            shEw.like("name", cn.get("name").toString());
        }
        if (cn.get("status") != null && StringUtils.isNotBlank(cn.get("status").toString())) {
            shEw.eq("status", cn.get("status").toString());
        }
        shEw.orderBy("id", false);
        return selectPage(page, shEw);
    }


    /**
     * 新增仓库
     */
    @Override
    public void saveStoreHouse(StorehouseDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("请登录后进行该操作");
        }
        String code = dto.getCode();
        String name = dto.getName();
        if (StringUtils.isBlank(code)) {
            throw new BaseException("仓库code不能为空");
        }
        if (StringUtils.isBlank(name)) {
            throw new BaseException("仓库名称不能为空");
        }
        EntityWrapper<Storehouse> shEW = new EntityWrapper<>();
        shEW.eq("code", code)
                .eq("name", name);
        int count = selectCount(shEW);
        if (count > 0) {
            throw new BaseException("该仓库信息已经存在");
        }
        Storehouse sh = new Storehouse();
        BeanUtils.copyProperties(dto, sh);
        sh.setId(flakeId.nextId());
        sh.setUserCreate(loginUser.getName());
        sh.setUserModified(loginUser.getName());
        insert(sh);
        // 关联插入节点
        List<StorehouseNodeDTO> nodes = dto.getStoreNodes();
        ArrayList<StorehouseNode> in = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(nodes)) {
            for (StorehouseNodeDTO node : nodes) {
                StorehouseNode shn = new StorehouseNode();
                shn.setId(flakeId.nextId());
                shn.setStoreHouseId(sh.getId());
                shn.setNodeId(node.getNodeId());
                shn.setStatus(Integer.valueOf(TableStatusEnum.STATUS_1.getCode()));
                shn.setRemark("新增绑定");
                shn.setUserCreate(loginUser.getName());
                shn.setUserModified(loginUser.getName());
                in.add(shn);
            }
        }
        if (CollectionUtils.isNotEmpty(in)) {
            storehouseNodeService.insertBatch(in);
        }
    }

    /**
     * 修改仓库
     */
    @Override
    public void updateStoreHouse(StorehouseDTO dto) {
        if (dto == null) {
            throw new BaseException("参数不能为空");
        }
        User loginUser = userService.getLoginUser();
        if (loginUser == null) {
            throw new BaseException("请登录后进行该操作");
        }
        String code = dto.getCode();
        String name = dto.getName();
        Long id = dto.getId();
        if (StringUtils.isBlank(code)) {
            throw new BaseException("仓库code不能为空");
        }
        if (StringUtils.isBlank(name)) {
            throw new BaseException("仓库名称不能为空");
        }
        if (id == null) {
            throw new BaseException("仓库id不能为空");
        }
        //增加仓库名称唯一性校验
        EntityWrapper<Storehouse> ew = new EntityWrapper<>();
        ew.eq("name", dto.getName())
                .ne("id", dto.getId());
        int i = selectCount(ew);
        if (i > 0) {
            throw new BaseException("仓库名称已经存在");
        }
        Storehouse sh = new Storehouse();
        BeanUtils.copyProperties(dto, sh);
        sh.setId(dto.getId());
        sh.setGmtModified(null);
        updateById(sh);
        //查询关联表中所有的关联
        EntityWrapper<StorehouseNode> shnEW = new EntityWrapper<>();
        shnEW.eq("store_house_id", id);
        List<StorehouseNode> oldNodes = storehouseNodeService.selectList(shnEW);
        LinkedList<Long> lls = new LinkedList<>();
        if (CollectionUtils.isNotEmpty(oldNodes)) {
            for (StorehouseNode on : oldNodes) {
                lls.add(on.getNodeId());
            }
        }
        //更改新关联节点
        compareAndSetNode(dto, loginUser, id, lls);
    }

    private void compareAndSetNode(StorehouseDTO dto, User loginUser, Long id, LinkedList<Long> lls) {
        List<StorehouseNodeDTO> nodes = dto.getStoreNodes();
        List<StorehouseNode> nodeCache = Lists.newArrayList();
        for (StorehouseNodeDTO node : nodes) {
            if (lls.contains(node.getNodeId())) {
                StorehouseNode en = new StorehouseNode();
                en.setStoreHouseId(id);
                en.setNodeId(node.getNodeId());
                en.setStatus(Integer.valueOf(TableStatusEnum.STATUS_1.getCode()));
                en.setRemark("修改绑定");
                en.setUserModified(loginUser.getName());
                nodeCache.add(en);
                EntityWrapper<StorehouseNode> shEW = new EntityWrapper<>();
                shEW.eq("store_house_id", id)
                        .eq("node_id", node.getNodeId());
                storehouseNodeService.update(en, shEW);
                lls.remove(node.getNodeId());// 已处理  从list移除
            } else {
                StorehouseNode en = new StorehouseNode();
                en.setId(flakeId.nextId());
                en.setStoreHouseId(id);
                en.setNodeId(node.getNodeId());
                en.setStatus(Integer.valueOf(TableStatusEnum.STATUS_1.getCode()));
                en.setRemark("新增绑定");
                en.setUserCreate(loginUser.getName());
                en.setUserModified(loginUser.getName());
                storehouseNodeService.insert(en);
            }
        }
        if (CollectionUtils.isNotEmpty(lls)) {
            for (Long remainId : lls) {
                StorehouseNode en = new StorehouseNode();
                en.setStoreHouseId(id);
                en.setNodeId(remainId);
                en.setStatus(Integer.valueOf(TableStatusEnum.STATUS_0.getCode()));
                en.setRemark("去除绑定");
                en.setUserModified(loginUser.getName());
                EntityWrapper<StorehouseNode> shEW = new EntityWrapper<>();
                shEW.eq("store_house_id", id)
                        .eq("node_id", remainId);
                storehouseNodeService.update(en, shEW);
            }
        }
    }

    /**
     * 编辑仓库 信息回显
     */
    @Override
    public List<StorehouseNodeDTO> getHoseInfo(Map<String, String> condition) {
        //查所有的 节点
        EntityWrapper<NodeOption> noEW = new EntityWrapper<>();
        noEW.eq("status", TableStatusEnum.STATUS_10.getCode())
                .orderBy("id");
        List<NodeOption> options = optionService.selectList(noEW);
        List<StorehouseNodeDTO> nodes = Lists.newArrayList();
        for (NodeOption no : options) {
            StorehouseNodeDTO nodeDTO = new StorehouseNodeDTO();
            nodeDTO.setNodeFlag(TableStatusEnum.STATUS_0.getCode());
            if (StringUtils.isNotBlank(condition.get("houseId"))) {
                EntityWrapper<StorehouseNode> snEW = new EntityWrapper<>();
                snEW.eq("store_house_id", condition.get("houseId"))
                        .eq("node_id", no.getId())
                        .eq("status", TableStatusEnum.STATUS_1.getCode());
                int count = storehouseNodeService.selectCount(snEW);
                if (count > 0) {
                    nodeDTO.setNodeFlag(TableStatusEnum.STATUS_1.getCode());
                }
            }
            nodeDTO.setNodeId(no.getId());
            nodeDTO.setNodeCode(no.getCode());
            nodeDTO.setNodeName(no.getName());
            nodeDTO.setNodeStatus(no.getStatus());
            nodes.add(nodeDTO);
        }
        return nodes;
    }

    @Override
    public Page<Storehouse> allUsableStoreHouse(Page<Storehouse> page) {
        Map<String, Object> condition = page.getCondition();
        Wrapper<Storehouse> ew = new EntityWrapper<>();
        if (StringUtils.isNotBlank(condition.get("name").toString())) {
            ew.like("code", condition.get("name").toString());
        }
        ew.eq("status", TableStatusEnum.STATUS_10.getCode());
        List<Storehouse> storehouses = baseMapper.selectPage(page, ew);
        page.setRecords(storehouses);
        return page;
    }

}
